package biz.innovasoft.nodb.transaction;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.prevayler.Transaction;

import biz.innovasoft.nodb.impl.GenericRepository;
import biz.innovasoft.nodb.query.Tuple;

public class UpdateUpdateableListTransaction implements Transaction {

	private static final long serialVersionUID = 1L;
	
	private List<Tuple> tuples;
	
	public UpdateUpdateableListTransaction (List<Tuple> tuples) {
		this.tuples = tuples;
	}
	
	@Override
	public void executeOn(Object system, Date time) {
		GenericRepository repo = (GenericRepository)system;
		List<?> storeList = this.getObjectsToStore(tuples);
		List<Long> deleteList = this.getObjectsToDelete(tuples);
		List<Tuple> updateList = this.getObjectsToUpdate(tuples);
		
		/*
		 * Store new objects.
		 */
		if (storeList != null && storeList.size() > 0) {
			repo.store(storeList);
		}
		
		/*
		 * Update objects.
		 */
		if (updateList != null && updateList.size() > 0) {
			repo.update(updateList);
		}
		
		/*
		 * Delete objects marked for deletion.
		 */
		if (deleteList != null && deleteList.size() > 0) {
			repo.delete(deleteList.toArray(new Long[0]));
		}
	}
	
	public List<?> getObjectsToStore(List<Tuple> tuples) {
		List<Object>added = new ArrayList<Object>();
		for (Tuple tuple : tuples) {
			if (tuple.oid == 0)
				added.add(tuple.value);
		}
		return added;
	}

	public List<Long> getObjectsToDelete(List<Tuple> tuples) {
		List<Long>removed = new ArrayList<Long>();
		for (Tuple tuple : tuples) {
			if (tuple.deleted)
				removed.add(tuple.oid);
		}
		return removed;
	}
	
	public List<Tuple> getObjectsToUpdate (List<Tuple> tuples) {
		List<Tuple>update = new ArrayList<Tuple>();
		for (Tuple tuple : tuples) {
			if (!tuple.deleted && tuple.oid != 0)
				update.add(tuple);
		}
		return update;
	}

}
